//
//  QuoteLvMinIndex.c
//  GAQuoteTradeLib
//
//  Created by  on 11-9-21.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#include "QuoteLvMinIndex.h"

/**计算估算标准差
 *
 *  @param double			aPoint			数组操作指针
 *  @param int				aCycle			周期（K线数量）
 *  @param int				aM				权重（K线数量）
 *  @param double			avg				平均值
 *
 *  @return -
 * 注释:
 *		
 */
double calcEMA(double aPreEMA, double x, int aCycle)
{
	double y=(2*x+(aCycle-1)*aPreEMA)/(aCycle+1);
	return y;
}

/**计算MA值
 *
 *  @param double			*aPoint			数组操作指针
 *  @param int				aStartPos		起始位置
 *  @param int				aCycle			周期（K线数量）
 *  @param int				aM				权重（K线数量）
 *
 *  @return -
 *
 *		
 */
double calcArrayMA(double aPoint[], int aStartPos, int aCycle)
{
	int i = aStartPos - aCycle + 1;
	double ma = 0;
	double nMax = 0;
  
	if (i < 0)
	{
		return ma;
	}
  
	for (; i<=aStartPos; i++)
	{
		nMax += aPoint[i];
	}
  
	ma = nMax/aCycle;
  
	return ma;
}

double QuoteLvMinIndex_RSV(QUOTELV_MIN_INDEX* aMinIndex, QUOTELV_MIN_POINT* aPoint, int aMinCount, int aStartPos);

/**计算周期内的最小值
 *
 *  @param QUOTELV_MIN_POINT	*aPoint			分时点结构指针
 *  @param aKCount			aMinCount		分时的数量
 *  @param int				aStartPos		起始位置
 *  @param char			aCycle			周期
 *
 *  @return -
 *
 *		
 */
double QuoteLvMinIndex_LLV(QUOTELV_MIN_POINT* aPoint,int aMinCount, int aStartPos, int aCycle);

/**计算周期内的最大值
 *
 *  @param QUOTELV_MIN_POINT	*aPoint			分时点结构指针
 *  @param aKCount			aMinCount		分时的数量
 *  @param int				aStartPos		起始位置
 *  @param char				aCycle			周期
 *
 *  @return -
 *
 *		
 */
double QuoteLvMinIndex_HHV(QUOTELV_MIN_POINT* aPoint,int aMinCount, int aStartPos, int aCycle);

/**计算SMA值
 *
 *  @param QUOTELV_K_INDEX	*aMinIndex		K线操作结构指针
 *  @param int				aCycle			周期（K线数量）
 *  @param int				aM				权重（K线数量）
 *
 *  @return -
 *
 *		
 */
double QuoteLvMinIndex_calcSMA(double aPreEMA, double x, int aCycle, double aM);

/**计算满足条件的周期数
 *
 *  @param QUOTELV_MIN_POINT			aPoint			数组操作指针
 *  @param int						aStartPos		起始位置
 *  @param int						aCycle			周期（K线数量）
 *
 *  @return -
 *
 *		
 */
double QuoteLvMinIndex_calcCOUNT(QUOTELV_MIN_POINT* aPoint, int aStartPos, int aCycle);

/**计算报价MA值
 *
 *  @param QUOTELV_MIN_POINT			aPoint			数组操作指针
 *  @param int				aStartPos		起始位置
 *  @param int				aCycle			周期（K线数量）
 *  @param int				aM				权重（K线数量）
 *
 *  @return -
 *
 *		
 */
double QuoteLvMinIndex_calcMA(QUOTELV_MIN_POINT* aPoint, int aStartPos, int aCycle);

QUOTELV_MIN_INDEX* QuoteLvMinIndex_New()
{
  QUOTELV_MIN_INDEX *minIndex = (QUOTELV_MIN_INDEX*)Tools_Malloc(sizeof(QUOTELV_MIN_INDEX));
	memset(minIndex->DDX.ddx,0,sizeof(minIndex->DDX.ddx));
	memset(minIndex->DDX.ddxSum,0,sizeof(minIndex->DDX.ddxSum));
	memset(minIndex->BBD.bbd,0,sizeof(minIndex->BBD.bbd));
	//add by jason 
	//初始化KDJ参数
	minIndex->KDJ_N = 9;
	minIndex->KDJ_M1 = 3;
	minIndex->KDJ_M2 = 3;
	
	//初始化RSI参数
	minIndex->RSI_N1 = 6;
	minIndex->RSI_N2 = 12;
	minIndex->RSI_N3 = 24;
	
	//初始化MACD参数
	minIndex->MACD_SHORT = 12;
	minIndex->MACD_LONG = 26;
	minIndex->MACD_MID = 9;
	//end
  return minIndex;
}

void QuoteLvMinIndex_calcDDX(QUOTELV_MIN_INDEX* aMinIndex,
                             QUOTELV_MIN_RES* aRes)
{
	memset(aMinIndex->DDX.ddx,0,sizeof(aMinIndex->DDX.ddx));
	memset(aMinIndex->DDX.ddxSum,0,sizeof(aMinIndex->DDX.ddxSum));

	
	if (aRes->nLeve2TotalCount>0) {
    aMinIndex->DDX.ddx[0] = aRes->leve2MinData[0].lMainVolumeDiff*100.0/aRes->lFloatShare;
    aMinIndex->DDX.ddxSum[0] = aMinIndex->DDX.ddx[0];
  }
  for (int i = 1; i < aRes->nLeve2TotalCount; i++) {
    aMinIndex->DDX.ddx[i] = aRes->leve2MinData[i].lMainVolumeDiff*100.0/aRes->lFloatShare;
    aMinIndex->DDX.ddxSum[i] = aMinIndex->DDX.ddxSum[i-1]+aMinIndex->DDX.ddx[i];
  }
//  int effectiveCycle = min(MIN_INDEX_L2XX_N1, aRes->nLeve2TotalCount);
//  
//  int i = 1;
//  aMinIndex->DDX.ddx1[0] = aMinIndex->DDX.ddx[0];
//	for(; i<aRes->nLeve2TotalCount; i++)
//	{
//		aMinIndex->DDX.ddx1[i] = calcEMA(aMinIndex->DDX.ddx1[i-1], aMinIndex->DDX.ddx[i],effectiveCycle);
//	}
//  
//  for (i=0; i <aRes->nLeve2TotalCount; i++) {
//    aMinIndex->DDX.ddx1[i] = aMinIndex->DDX.ddx1[i]*effectiveCycle;
//  }
//  
//  for (i = 0; i < aRes->nLeve2TotalCount; i++) {
//    aMinIndex->DDX.ddx2[i] = calcArrayMA(aMinIndex->DDX.ddx1, i, MIN_INDEX_L2XX_N2);
//    aMinIndex->DDX.ddx3[i] = calcArrayMA(aMinIndex->DDX.ddx1, i, MIN_INDEX_L2XX_N3);
//  }
}

void QuoteLvMinIndex_calcBBD(QUOTELV_MIN_INDEX* aMinIndex,
                             QUOTELV_MIN_RES* aRes)
{
	memset(aMinIndex->BBD.bbd,0,sizeof(aMinIndex->BBD.bbd));
	
  if (aRes->nLeve2TotalCount>0) {
    //特大+大
    aMinIndex->BBD.bbd[0] = aRes->leve2MinData[0].lBiggerAmountDiff + aRes->leve2MinData[0].lBigAmountDiff;
  }
  
  for (int i=1; i < aRes->nLeve2TotalCount; i++) {
    aMinIndex->BBD.bbd[i] = (aRes->leve2MinData[i].lBiggerAmountDiff + aRes->leve2MinData[i].lBigAmountDiff);//aMinIndex->BBD.bbd[i-1] + 
  }
}

void QuoteLvMinIndex_calcKDJ(QUOTELV_MIN_INDEX* aMinIndex, QUOTELV_MIN_RES* aRes)
{
  int i = 0;
  double RSVt[KLIN_MAX_NUM];
  int count = aRes->nTotalCount;					//计算的个数（总数-周期数-起始位置）
	
  for(i=0; i<count; i++)
  {
		RSVt[i] = QuoteLvMinIndex_RSV(aMinIndex,aRes->minData,aRes->nTotalCount,i);
  }
	
  aMinIndex->KDJ.K[0] = RSVt[0];
  aMinIndex->KDJ.D[0] = RSVt[0];
	
  for(i=1; i<count; i++)
  {
		aMinIndex->KDJ.K[i] = QuoteLvMinIndex_calcSMA(aMinIndex->KDJ.K[i-1],RSVt[i],aMinIndex->KDJ_M1,1);
		
  }
	
  for (i=1; i<count; i++)
  {
		aMinIndex->KDJ.D[i] = QuoteLvMinIndex_calcSMA(aMinIndex->KDJ.D[i-1], aMinIndex->KDJ.K[i], aMinIndex->KDJ_M2,1);
  }
	
  for (i = 0; i < count; i++) {
		aMinIndex->KDJ.J[i] = 3*aMinIndex->KDJ.K[i] - 2*aMinIndex->KDJ.D[i];
  }
	
  aMinIndex->KDJ.J[0] = aMinIndex->KDJ.D[0];
}

void QuoteLvMinIndex_calcMACD(QUOTELV_MIN_INDEX* aMinIndex, QUOTELV_MIN_RES* aRes)
{
  int count;
  int i;
	
  aMinIndex->MACD.DIF[0] = 0;
  aMinIndex->MACD.DEA[0] = 0;
  aMinIndex->MACD.MACD[0] = 0;
	
	
  aMinIndex->MACD.shortEMA[0] = aRes->minData[0].fPri;
  aMinIndex->MACD.longEMA[0] = aRes->minData[0].fPri;
  count = aRes->nTotalCount;					//计算的个数（总数-周期数-起始位置）
	
  i = 1;
  for(; i<count; i++)
  {
		aMinIndex->MACD.shortEMA[i] = calcEMA(aMinIndex->MACD.shortEMA[i-1],aRes->minData[i].fPri,aMinIndex->MACD_SHORT);
		aMinIndex->MACD.longEMA[i] = calcEMA(aMinIndex->MACD.longEMA[i-1],aRes->minData[i].fPri,aMinIndex->MACD_LONG);
		aMinIndex->MACD.DIF[i] = aMinIndex->MACD.shortEMA[i]- aMinIndex->MACD.longEMA[i];
		aMinIndex->MACD.DEA[i] = calcEMA(aMinIndex->MACD.DEA[i-1],aMinIndex->MACD.DIF[i],aMinIndex->MACD_MID);
		aMinIndex->MACD.MACD[i] = (aMinIndex->MACD.DIF[i] - aMinIndex->MACD.DEA[i])*2;
  }
}

void QuoteLvMinIndex_calcRSI(QUOTELV_MIN_INDEX* aMinIndex, QUOTELV_MIN_RES* aRes)
{
  int i = 1;
  //int j = 1;
  //double rsi = 0;
  double maxSMA[KLIN_MAX_NUM];
  double absSMA[KLIN_MAX_NUM];
	
  maxSMA[0] = 0;
  absSMA[0] = 0;
	
  for(i=1; i<aRes->nTotalCount; i++)
  {
		maxSMA[i] = QuoteLvMinIndex_calcSMA(maxSMA[i-1],max(aRes->minData[i].fPri - aRes->minData[i-1].fPri,0),aMinIndex->RSI_N1,1);
		absSMA[i] = QuoteLvMinIndex_calcSMA(absSMA[i-1],fabs(aRes->minData[i].fPri - aRes->minData[i-1].fPri),aMinIndex->RSI_N1,1);
		if (absSMA[i] == 0){
			aMinIndex->RSI.RSI1[i] = 0;
		}else{
			aMinIndex->RSI.RSI1[i] = maxSMA[i] / absSMA[i] * 100;
		}
		
  }
  aMinIndex->RSI.RSI1[0] = 0; 
	
  maxSMA[0] = 0;//max(aRes->minData[0].fPri,0)/aMinIndex->RSI_N2;
  absSMA[0] = 0;//fabs(aRes->minData[0].fPri)/aMinIndex->RSI_N2;
  //rsi = maxSMA[0] /absSMA[0]*100;
	
  for(i=1; i<aRes->nTotalCount; i++)
  {
		maxSMA[i] = QuoteLvMinIndex_calcSMA(maxSMA[i-1],max(aRes->minData[i].fPri - aRes->minData[i-1].fPri,0),aMinIndex->RSI_N2,1);
		absSMA[i] = QuoteLvMinIndex_calcSMA(absSMA[i-1],fabs(aRes->minData[i].fPri - aRes->minData[i-1].fPri),aMinIndex->RSI_N2,1);
		if (absSMA[i] == 0){
			aMinIndex->RSI.RSI2[i] = 0;
		}else{
			aMinIndex->RSI.RSI2[i] = maxSMA[i] / absSMA[i] * 100;
		}
  }
  aMinIndex->RSI.RSI2[0] = 0 ;
	
  maxSMA[0] = 0;//max(aRes->minData[0].fPri,0)/aMinIndex->RSI_N3;
  absSMA[0] = 0;//fabs(aRes->minData[0].fPri)/aMinIndex->RSI_N3;
  //rsi = maxSMA[0] /absSMA[0]*100;
	
  for(i=1; i<aRes->nTotalCount; i++)
  {
		maxSMA[i] = QuoteLvMinIndex_calcSMA(maxSMA[i-1],max(aRes->minData[i].fPri - aRes->minData[i-1].fPri,0),aMinIndex->RSI_N3,1);
		absSMA[i] = QuoteLvMinIndex_calcSMA(absSMA[i-1],fabs(aRes->minData[i].fPri - aRes->minData[i-1].fPri),aMinIndex->RSI_N3,1);
		if (absSMA[i] == 0){
			aMinIndex->RSI.RSI3[i] = 0;
		}else{
			aMinIndex->RSI.RSI3[i] = maxSMA[i] / absSMA[i] * 100;
		}
  }
  aMinIndex->RSI.RSI3[0] = 0;
}

double QuoteLvMinIndex_RSV(QUOTELV_MIN_INDEX* aMinIndex, QUOTELV_MIN_POINT* aPoint, int aMinCount, int aStartPos)
{
  double RSVt = 0;
  double low = QuoteLvMinIndex_LLV(aPoint,aMinCount,aStartPos,aMinIndex->KDJ_N);				//计算周期内的最小值
  double high = QuoteLvMinIndex_HHV(aPoint,aMinCount, aStartPos,aMinIndex->KDJ_N);				//计算周期内的最大值
	
  if (low == 0 || high == 0 || low == high) {
		RSVt = 50;
  }
  else {
		RSVt = (( aPoint[aStartPos].fPri - low)/(high - low))*100;
  }
	
  return RSVt;
}

double QuoteLvMinIndex_LLV(QUOTELV_MIN_POINT* aPoint,int aMinCount, int aStartPos, int aCycle)
{
  int i = aStartPos - aCycle + 1  > 0 ? aStartPos - aCycle + 1 : 0;					////判断是否满足周期，如果不满足，有多少计算多少
  double low = aPoint[aStartPos].fPri;
	
  for(; i<aStartPos; i++)
  {
		low = low < aPoint[i].fPri ? low : aPoint[i].fPri;
  }
	
	
  return low;
}

double QuoteLvMinIndex_HHV(QUOTELV_MIN_POINT* aPoint,int aMinCount, int aStartPos, int aCycle)
{
  int i = aStartPos - aCycle + 1 > 0 ? aStartPos - aCycle + 1 : 0;
  double high = aPoint[aStartPos].fPri;
	
  for(; i<aStartPos; i++)
  {
		high = high > aPoint[i].fPri ? high : aPoint[i].fPri;
  }
	
  return high;
}

double QuoteLvMinIndex_calcSMA(double aPreEMA, double x, int aCycle, double aM)
{
  double y=(aM/aCycle)*x+(aCycle-aM)*aPreEMA/(aCycle);
  return y;
}

double QuoteLvMinIndex_calcCOUNT(QUOTELV_MIN_POINT* aPoint, int aStartPos, int aCycle)
{
  int i = aStartPos - aCycle + 1;
  double nCount = 0;
  i  = i < 1 ? 1 : i;
	
  for (; i<=aStartPos; i++)
  {
		if (aPoint[i].fPri > aPoint[i-1].fPri) {
			nCount++;
		}
  }
  return nCount;
}

double QuoteLvMinIndex_calcMA(QUOTELV_MIN_POINT* aPoint, int aStartPos, int aCycle)
{
  int i = aStartPos - aCycle + 1;
  double ma = 0;
  double nMax = 0;
	
  if (i < 0)
  {
		return ma;
  }
	
  for (; i<=aStartPos; i++)
  {
		nMax += aPoint[i].fPri;
  }
	
  ma = nMax/aCycle;
	
  return ma;
}